package com.jzr.bedside.ui.skill

import android.content.Intent
import android.util.Log
import android.view.View
import android.view.ViewTreeObserver
import android.widget.Button
import android.widget.ImageView
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.andy.ecgviewlib.EcgViewInterface
import com.andy.ecgviewlib.EcgWaveView
import com.blankj.utilcode.utils.TimeUtils
import com.blankj.utilcode.utils.ToastUtils
import com.google.gson.Gson
import com.inuker.bluetooth.library.Constants
import com.inuker.bluetooth.library.connect.listener.BleConnectStatusListener
import com.inuker.bluetooth.library.connect.options.BleConnectOptions
import com.inuker.bluetooth.library.connect.response.BleNotifyResponse
import com.inuker.bluetooth.library.search.SearchRequest
import com.inuker.bluetooth.library.search.SearchResult
import com.inuker.bluetooth.library.search.response.SearchResponse
import com.inuker.bluetooth.library.utils.BluetoothLog
import com.jzr.bedside.R
import com.jzr.bedside.base.BaseActivity
import com.jzr.bedside.base.BaseApplication
import com.jzr.bedside.bean.TemperatureBean
import com.jzr.bedside.bean.body.OximeterBody
import com.jzr.bedside.bean.body.TemperatureAddBody
import com.jzr.bedside.presenter.contract.OximeterActivityContract
import com.jzr.bedside.presenter.impl.OximeterActivityImpl
import com.jzr.bedside.service.BluetoothChipType
import com.jzr.bedside.service.BluetoothUtils
import com.jzr.bedside.ui.adapter.DeviceAdapter
import com.jzr.bedside.utils.BluetoothUtil
import com.jzr.bedside.utils.Permission
import com.jzr.bedside.utils.PreferUtil
import com.jzr.bedside.view.CustomDialog
import com.medxing.sdk.resolve.ResolveManager
import com.orhanobut.logger.Logger
import kotlinx.android.synthetic.main.actionbar_root_layout.*
import kotlinx.android.synthetic.main.activity_oximeter.*
import kotlinx.android.synthetic.main.activity_oximeter.btnStartSean
import kotlinx.android.synthetic.main.activity_temperature.*
import okhttp3.MediaType
import okhttp3.RequestBody
import java.util.*

class OximeterActivity : BaseActivity(), View.OnClickListener, OximeterActivityContract.View {

    private var mPresetr = OximeterActivityImpl()

    private var diaologDevice: CustomDialog? = null
    private var diaologScan: CustomDialog? = null
    private var diaologAgainScan: CustomDialog? = null
    private var devices = mutableListOf<SearchResult>()

    private var resolveManager: ResolveManager? = null
    private val bluetoothChipType: BluetoothChipType = BluetoothChipType()

    private var bcgWaveView: EcgWaveView? = null
    private var view: View? = null
    private var address: String? = null


    override fun getLayoutId(): Int {
        return R.layout.activity_oximeter
    }

    override fun attachView() {
        mPresetr.attachView(this)
    }

    override fun detachView() {
        mPresetr.detachView()
    }

    private fun showDiaologScan() {
        hideScanDialog()
        val view = View.inflate(BaseApplication.getContext(), R.layout.dialog_scan, null)
        diaologScan = CustomDialog(this, 300, 250, view, R.style.MyDialog)
        diaologScan?.setCancelable(false)
        diaologScan?.show()
    }

    /**
     * 再次连接
     */
    private fun showDiaologAgainScan() {
//        llDash.visibility = View.GONE
        hideAgainScanDialog()
        val view = View.inflate(BaseApplication.getContext(), R.layout.dialog_again_scan, null)
        val btnAgainScan = view.findViewById<Button>(R.id.btnAgainScan)
        btnAgainScan.setOnClickListener {
            hideAgainScanDialog()
            searchDevice()
        }
        diaologScan = CustomDialog(this, 300, 250, view, R.style.MyDialog)
        diaologScan?.setCancelable(true)
        diaologScan?.show()
    }

    /**
    蓝牙设备列表dialog
     */
    private fun showDeviceDialog(devices: MutableList<SearchResult>?) {

        hideDeviceDialog()
        val view = View.inflate(BaseApplication.getContext(), R.layout.dialog_device_list, null)
        val ivDelete = view.findViewById<ImageView>(R.id.ivDelete)
        val rvDevice = view.findViewById<RecyclerView>(R.id.rvDevice)
        val btnAgSeach = view.findViewById<Button>(R.id.btnAgSeach)

        val adapter = DeviceAdapter(devices)
        rvDevice.adapter = adapter
        val manager = LinearLayoutManager(this)
        rvDevice.layoutManager = manager

        adapter.onListItemClick(object : DeviceAdapter.onListItemClick {
            override fun onListItemClick(item: SearchResult?) {
                hideDeviceDialog()
                connect(item)
            }
        })

        ivDelete.setOnClickListener {
            hideDeviceDialog()
        }
        btnAgSeach.setOnClickListener {
            hideDeviceDialog()
            searchDevice()
        }

        diaologDevice = CustomDialog(this, view, R.style.MyDialog)
        diaologDevice?.setCancelable(false)
        diaologDevice?.show()

    }

    private fun hideDeviceDialog() {
        if (diaologDevice != null && diaologDevice?.isShowing!!) {
            diaologDevice?.dismiss()
            diaologDevice = null
        }
    }

    private fun hideScanDialog() {
        if (diaologScan != null && diaologScan?.isShowing!!) {
            diaologScan?.dismiss()
            diaologScan = null
        }
    }

    private fun hideAgainScanDialog() {
        if (diaologAgainScan != null && diaologAgainScan?.isShowing!!) {
            diaologAgainScan?.dismiss()
            diaologAgainScan = null
        }
    }

    override fun initView() {

//        searchDevice()
        ivRight.setOnClickListener(this)
        btnStartSean.setOnClickListener(this)
//        llDash.visibility = View.GONE
        dashLeft.setContext("血氧饱和度(%)")
        dashRight.setContext("脉博率(bmp)")

        resolveManager = ResolveManager.getInstance(this)
        resolveManager?.setOnSpo2ResolveListener { spo2PackageData, spo2PackageWave, spo2PackageHRV ->
            if (spo2PackageData != null) {

                dashRight.setCurrentNumAnim(spo2PackageData.pulse)
                dashLeft.setCurrentNumAnim(spo2PackageData.box)

                val dataList = mutableListOf<OximeterBody>()
                val body = OximeterBody()

                body.patientId = PreferUtil.getInstance().patientId!!
                body.bedNo = PreferUtil.getInstance().bedCode
                body.admissionId = PreferUtil.getInstance().cureNo
//                body.createTime = TimeUtils.getNowTimeString()
                body.pulse = spo2PackageData.pulse.toDouble()
                body.oxySat = spo2PackageData.box.toDouble()
                body.name = PreferUtil.getInstance().name
                dataList.add(body)

                val bodys: RequestBody =
                    RequestBody.create(
                        MediaType.parse("application/json; charset=utf-8"),
                        Gson().toJson(dataList)
                    )

                mPresetr.getOxymeterAdd(this, bodys)

            } else if (spo2PackageWave != null) {
                for (i in spo2PackageWave.pulseLevel.indices) {
                    val level = spo2PackageWave.pulseLevel[i]
                    val y =
                        (500 * Math.sin(2 * Math.PI * level / 80) + 500).toInt()
                    bcgWaveView?.drawWave(y)
                }
            } else if (spo2PackageHRV != null) {

            }
        }

//        view = window.decorView
//        view?.viewTreeObserver?.addOnGlobalLayoutListener { globalLayoutListener }
//            fun onGlobalLayout() {
//                val width = llFather.width
//                val height = llFather.height
//
//                bcgWaveView = EcgWaveView(baseContext, width, height);
//                bcgWaveView?.listener = ecgViewListener
//                bcgWaveView?.setN_frequency(0.0)
//                bcgWaveView?.sampleRe = 8096
//                bcgWaveView?.sampleV = 10
//                bcgWaveView?.isWaveAdapter = true;
//                bcgWaveView?.init()
//                llFather.addView(bcgWaveView)
//
////                view?.viewTreeObserver?.removeOnGlobalLayoutListener()
//            }
//        }
    }

//    private val globalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener {
//        val width = llFather.width
//        val height = llFather.height

//        bcgWaveView = EcgWaveView(baseContext, width, height);
//        bcgWaveView?.listener = ecgViewListener
//        bcgWaveView?.setN_frequency(0.0)
//        bcgWaveView?.sampleRe = 8096
//        bcgWaveView?.sampleV = 10
//        bcgWaveView?.isWaveAdapter = true;
//        bcgWaveView?.init()
//        llFather.addView(bcgWaveView)
//    }


    fun searchDevice() {
        if (!BluetoothUtil.getClient().isBluetoothOpened) {
            BluetoothUtil.getClient().openBluetooth()
        }
        val request = SearchRequest.Builder()
            .searchBluetoothLeDevice(5000, 3)
            .build()
        BluetoothUtil.getClient().search(request, object : SearchResponse {
            override fun onSearchStarted() {

                Permission.requestPermission(this@OximeterActivity)
                showDiaologScan()
            }

            override fun onDeviceFounded(device: SearchResult) {
                if (device.name == "MEDXING-SpO2") {
                    if (!devices.contains(device)) {
                        devices.add(device)
                    }
                }
            }

            override fun onSearchStopped() {
                hideScanDialog()
                if (devices.size > 0) {
                    showDeviceDialog(devices)
                } else {
                    showDiaologAgainScan()
                }

            }

            override fun onSearchCanceled() {

            }
        })
    }

    private fun connect(item: SearchResult?) {
        showLoadingDialog("正在连接中....")
        val options = BleConnectOptions.Builder()
            .setConnectRetry(3)
            .setConnectTimeout(1000)
            .setServiceDiscoverRetry(1)
            .setServiceDiscoverTimeout(1000)
            .build()
        BluetoothUtil.getClient().connect(
            item?.address, options
        ) { code, profile ->
            dismissLoadingDialog()
            when (code) {
                Constants.REQUEST_SUCCESS -> {
                    bluetoothChipType.mac = item?.address
                    address = item?.address
                    val chipType = BluetoothUtils.checkChipType(profile)
                    if (chipType > -1) {
                        BluetoothUtils.setBluetoothChipType(bluetoothChipType)
                        startNotify()
                        BluetoothUtil.getClient()
                            .registerConnectStatusListener(item?.address, mConnectStatusListener)
                        ToastUtils.showLongToastSafe("连接成功...")
                        llDash.visibility = View.VISIBLE
                    } else {
                        ToastUtils.showLongToastSafe("连接失败...")
                        showDiaologAgainScan()
                    }
                }
                Constants.REQUEST_FAILED -> {
                    ToastUtils.showLongToastSafe("连接失败...")
                    showDiaologAgainScan()
                }

                Constants.REQUEST_TIMEDOUT -> {
                    ToastUtils.showLongToastSafe("连接超时...")
                    showDiaologAgainScan()
                }
            }
        }

    }

    private fun startNotify() {
        if (bluetoothChipType.isAvailable) {
            BluetoothUtil.getClient().notify(
                bluetoothChipType.mac,
                bluetoothChipType.serviceUUID,
                bluetoothChipType.notificationUUID,
                object :
                    BleNotifyResponse {
                    override fun onNotify(
                        service: UUID,
                        character: UUID,
                        value: ByteArray
                    ) {
//                        Logger.e("run: " + TypeCastUtil.bytesToHexString(value));
                        resolveManager?.pushData(*value)
                    }

                    override fun onResponse(code: Int) {}
                })
        }

    }


    override fun onDestroy() {
        super.onDestroy()
        BluetoothUtil.getClient().unregisterConnectStatusListener(address, mConnectStatusListener)
        BluetoothUtil.getClient().disconnect(address)
//        view?.viewTreeObserver?.removeOnGlobalLayoutListener(globalLayoutListener)
    }

    private val ecgViewListener: EcgViewInterface = object : EcgViewInterface {
        override fun onError(e: Exception) {}
        override fun onShowMessage(t: String, i: Int) {
            Log.i("tag", "心电接口回调--》$t")
            if (i == 0) {
                //  Toast.makeText(getApplication(),"时间：" + t + "ms/格",Toast.LENGTH_SHORT).show();
            } else if (i == 1) {
                //   Toast.makeText(getApplication(),"电压："+t+"mv/格",Toast.LENGTH_SHORT).show();
            }
        }
    }

    private val mConnectStatusListener: BleConnectStatusListener =
        object : BleConnectStatusListener() {
            override fun onConnectStatusChanged(mac: String, status: Int) {
                val mConnected = status == Constants.STATUS_CONNECTED
                if (!mConnected) {
                    showDiaologAgainScan()
                }
            }
        }

    override fun onClick(v: View?) {
        when (v?.id) {
            R.id.ivRight -> {
                finish()
            }
            R.id.btnStartSean -> {
                searchDevice()
            }
        }
    }

    override fun getOxymeterAddSuccess(data: TemperatureBean?) {

    }

    override fun showError(message: String?) {
        ToastUtils.showShortToastSafe(message)
    }

}
